﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace HOOMT
{
    public abstract class OriginalLine
    {
        #region 属性
        public string parentFormId;
        public string id;
        protected Point startPoint;
        protected Point endPoint;
        private bool isSelected;

        protected Font drawFont = new Font("Arial", 8);
        protected SolidBrush drawBrush = new SolidBrush(Color.Black);
        protected Pen pen = new Pen(Color.Brown, 1);

        private Size startDiagramSize, endDiagramSize;
        
        private OriginalDiagram startDiagram, endDiagram;

        private String lineName = "";

        public String LineName
        {
            get { return lineName; }
            set { lineName = value; }
        }
        private OriginalModelForm subForm;

        public OriginalModelForm SubForm
        {
            get { return subForm; }
            set { subForm = value; }
        }

        public OriginalDiagram StartDiagram
        {
            get { return startDiagram; }
            set { startDiagram = value; }
        }

        public OriginalDiagram EndDiagram
        {
            get { return endDiagram; }
            set { endDiagram = value; }
        }
        protected Point startShowPoint, endShowPoint;
        //###################################################################################
        #endregion
        public OriginalLine(Point startPoint, Point endPoint, OriginalDiagram startDiagram, OriginalDiagram endDiagram)
        {
            this.startPoint = startPoint;
            this.endPoint = endPoint;
            this.startDiagram = startDiagram;
            this.endDiagram = endDiagram;
            startDiagramSize = new Size(startDiagram.Width/2, startDiagram.Height/2);
            endDiagramSize = new Size(endDiagram.Width/2, endDiagram.Height/2);
            this.id = System.Guid.NewGuid().ToString();
            //lineNameBox.TextAlign = HorizontalAlignment.Center;
            //为NameBox添加鼠标响应函数
            //lineNameBox.MouseDown += new MouseEventHandler(nameBox_MouseDown);
        }
        public OriginalLine(Point startPoint, Point endPoint, string id, OriginalDiagram startDiagram, OriginalDiagram endDiagram)
        {

            this.startPoint = startPoint;
            this.endPoint = endPoint;
            this.startDiagram = startDiagram;
            this.endDiagram = endDiagram;
            startDiagramSize = new Size(startDiagram.Width/2, startDiagram.Height/2);
            endDiagramSize = new Size(endDiagram.Width/2, endDiagram.Height/2);
            this.id = id;
            //lineNameBox.TextAlign = HorizontalAlignment.Center;
            //为NameBox添加鼠标响应函数
            //lineNameBox.MouseDown += new MouseEventHandler(nameBox_MouseDown);
        }
        //************************************************************************************
        //NameBox鼠标事件响应函数
        //private void nameBox_MouseDown(object sender, MouseEventArgs e)
        //{
        //    if (e.Clicks == 2 && e.Button == MouseButtons.Left)
        //    {
        //        LineNameBox.SelectAll();
        //    }
        //    else if (e.Button == MouseButtons.Left)
        //    {
        //        LineNameBox.SelectionStart = LineNameBox.Text.Length;
        //    }
        //}
        
        //绘图函数
        //************************************************************************************
        public virtual void Drawing(Graphics g, OriginalModelForm m)
        {
            Pen pen = new Pen(Color.Brown, 1);
            g.DrawLine(pen, GetStartShowPoint(), GetEndShowPoint());

            g.DrawString(LineName, drawFont, drawBrush, new Point((GetStartShowPoint().X + GetEndShowPoint().X) / 2 - lineName.Length * 3, (GetStartShowPoint().Y + GetEndShowPoint().Y) / 2));
            //LineNameBox.Size = new Size(lineName.Length*6, 30);
            //LineNameBox.Location = new Point((GetStartShowPoint().X + GetEndShowPoint().X) / 2 - lineName.Length * 3, (GetStartShowPoint().Y + GetEndShowPoint().Y) / 2);
            //LineNameBox.Text = lineName;
            //LineNameBox.TabStop = false;//删除对象时光标不跳入下一个对象的TextBox
            //LineNameBox.BackColor = SystemColors.Window;//设置为与MainForm相同的颜色
            //LineNameBox.BorderStyle = System.Windows.Forms.BorderStyle.None;//取消边框
            //m.Controls.Add(LineNameBox);
           
        }
       

        //************************************************************************************
        //计算线条的显示段的两端点startShowPoint，endShowPoint
        public Point GetStartShowPoint()
        {
            //减15为防止图形对象名称覆盖部分线段
            #region
            //直线变成平行或垂直的情况
            if (startPoint.X == endPoint.X && endPoint.Y > startPoint.Y)
            {
                startShowPoint.X = endShowPoint.X = startPoint.X;
                startShowPoint.Y = startPoint.Y + StartDiagramSize.Height;
                endShowPoint.Y = endPoint.Y - EndDiagramSize.Height-15;
            }
            else if (startPoint.X == endPoint.X && endPoint.Y < startPoint.Y)
            {
                startShowPoint.X = endShowPoint.X = startPoint.X;
                startShowPoint.Y = startPoint.Y - StartDiagramSize.Height-15;
                endShowPoint.Y = endPoint.Y + EndDiagramSize.Height;
            }
            else if (startPoint.X > endPoint.X && endPoint.Y == startPoint.Y)
            {
                startShowPoint.Y = endShowPoint.Y = startPoint.Y;
                startShowPoint.X = startPoint.X - StartDiagramSize.Width;
                endShowPoint.X = endPoint.X + EndDiagramSize.Width;
            }
            else if (startPoint.X < endPoint.X && endPoint.Y == startPoint.Y)
            {
                startShowPoint.Y = endShowPoint.Y = startPoint.Y;
                startShowPoint.X = startPoint.X + StartDiagramSize.Width;
                endShowPoint.X = endPoint.X - EndDiagramSize.Width;
            }
            //右上到左下
            else if (startPoint.X > endPoint.X && startPoint.Y < endPoint.Y)
            {
                //endShowPoint
                endShowPoint.Y = (startPoint.Y - endPoint.Y) * (endDiagramSize.Width) / (startPoint.X - endPoint.X) + endPoint.Y;
                if (endShowPoint.Y < endPoint.Y - endDiagramSize.Height-15)
                {
                    endShowPoint.Y = endPoint.Y - endDiagramSize.Height-15;
                    endShowPoint.X = (startPoint.X - endPoint.X) * (endShowPoint.Y - startPoint.Y) / (startPoint.Y - endPoint.Y) + startPoint.X;//
                }
                else
                {
                    endShowPoint.X = endPoint.X + endDiagramSize.Width;
                }
                //startShowPoint
                startShowPoint.Y = (startPoint.Y - endPoint.Y) * (startPoint.X - startDiagramSize.Width - endPoint.X) / (startPoint.X - endPoint.X) + endPoint.Y;
                if (startShowPoint.Y > startPoint.Y + startDiagramSize.Height)
                {
                    startShowPoint.Y = startPoint.Y + startDiagramSize.Height;
                    startShowPoint.X = (startPoint.X - endPoint.X) * (startShowPoint.Y - endPoint.Y) / (startPoint.Y - endPoint.Y) + endPoint.X;
                }
                else
                {
                    startShowPoint.X = startPoint.X - startDiagramSize.Width;
                }
            }
            //左下到右上
            else if (endPoint.X > startPoint.X && endPoint.Y < startPoint.Y)
            {
                //startShowPoint
                startShowPoint.Y = (endPoint.Y - startPoint.Y) * (startDiagramSize.Width) / (endPoint.X - startPoint.X) + startPoint.Y;
                if (startShowPoint.Y < startPoint.Y - startDiagramSize.Height-15)
                {
                    startShowPoint.Y = startPoint.Y - startDiagramSize.Height-15;
                    startShowPoint.X = (endPoint.X - startPoint.X) * (startShowPoint.Y - startPoint.Y) / (endPoint.Y - startPoint.Y) + startPoint.X;
                }
                else
                {
                    startShowPoint.X = startPoint.X + startDiagramSize.Width;
                }
                //endShowPoint
                endShowPoint.Y = (endPoint.Y - startPoint.Y) * (endPoint.X - endDiagramSize.Width - startPoint.X) / (endPoint.X - startPoint.X) + startPoint.Y;
                if (endShowPoint.Y > endPoint.Y + endDiagramSize.Height)
                {
                    endShowPoint.Y = endPoint.Y + endDiagramSize.Height;
                    endShowPoint.X = (endPoint.X - startPoint.X) * (endShowPoint.Y - startPoint.Y) / (endPoint.Y - startPoint.Y) + startPoint.X;
                }
                else
                {
                    endShowPoint.X = endPoint.X - endDiagramSize.Width;
                }
            }
            //左上到右下
            else if (startPoint.X < endPoint.X && startPoint.Y < endPoint.Y)
            {
                //endShowPoint
                endShowPoint.Y = (startPoint.Y - endPoint.Y) * (endPoint.X - endDiagramSize.Width - startPoint.X) / (startPoint.X - endPoint.X) + startPoint.Y;
                if (endShowPoint.Y < endPoint.Y - endDiagramSize.Height-15)
                {
                    endShowPoint.Y = endPoint.Y - endDiagramSize.Height-15;
                    endShowPoint.X = (startPoint.X - endPoint.X) * (endShowPoint.Y - startPoint.Y) / (startPoint.Y - endPoint.Y) + startPoint.X;
                }
                else
                {
                    endShowPoint.X = endPoint.X - endDiagramSize.Width;
                }
                //startShowPoint
                startShowPoint.Y = (startPoint.Y - endPoint.Y) * (startDiagramSize.Width) / (startPoint.X - endPoint.X) + startPoint.Y;
                if (startShowPoint.Y > startPoint.Y + startDiagramSize.Height)
                {
                    startShowPoint.Y = startPoint.Y + startDiagramSize.Height;
                    startShowPoint.X = (startPoint.X - endPoint.X) * (startShowPoint.Y - startPoint.Y) / (startPoint.Y - endPoint.Y) + startPoint.X;
                }
                else
                {
                    startShowPoint.X = startPoint.X + startDiagramSize.Width;
                }
            }
            //右下到左上
            else if (endPoint.X < startPoint.X && endPoint.Y < startPoint.Y)
            {
                //startShowPoint
                startShowPoint.Y = (endPoint.Y - startPoint.Y) * (startPoint.X - startDiagramSize.Width - endPoint.X) / (endPoint.X - startPoint.X) + endPoint.Y;
                if (startShowPoint.Y < startPoint.Y - startDiagramSize.Height-15)
                {
                    startShowPoint.Y = startPoint.Y - startDiagramSize.Height-15;
                    startShowPoint.X = (endPoint.X - startPoint.X) * (startShowPoint.Y - endPoint.Y) / (endPoint.Y - startPoint.Y) + endPoint.X;
                }
                else
                {
                    startShowPoint.X = startPoint.X - startDiagramSize.Width;
                }
                //endShowPoint
                endShowPoint.Y = (endPoint.Y - startPoint.Y) * (endDiagramSize.Width) / (endPoint.X - startPoint.X) + endPoint.Y;
                if (endShowPoint.Y > endPoint.Y + endDiagramSize.Height)
                {
                    endShowPoint.Y = endPoint.Y + endDiagramSize.Height;
                    endShowPoint.X = (endPoint.X - startPoint.X) * (endShowPoint.Y - startPoint.Y) / (endPoint.Y - startPoint.Y) + startPoint.X;
                }
                else
                {
                    endShowPoint.X = endPoint.X + endDiagramSize.Width;
                }
            }
            #endregion
            return startShowPoint;
        }
        //************************************************************************************
        public Point GetEndShowPoint()
        {
            return endShowPoint;
        }
        //************************************************************************************
        //判断直线的选中
        public bool IsSelectedLine(Point p/*鼠标点击点*/, Point p1, Point p2/*直线的两个端点*/)
        {
            //如果点击不在区域中，则返回false
            if (!(new Rectangle(
                (p1.X <= p2.X ? p1.X : p2.X) - 5,
                (p1.Y <= p2.Y ? p1.Y : p2.Y) - 5,
                (p1.X > p2.X ? p1.X : p2.X) + 5,
                (p1.Y > p2.Y ? p1.Y : p2.Y) + 5)).Contains(p))

                return false;

            //坐标变换
            p1.X -= p2.X;
            p1.Y -= p2.Y;
            p.X -= p2.X;
            p.Y -= p2.Y;
            p2.X = 0;
            p2.Y = 0;
            //计算距离

            double d = Math.Abs((float)(p1.Y * p.X - p1.X * p.Y)) / Math.Sqrt((float)(p1.Y * p1.Y + p1.X * p.X));

            if (d < 10/* 更改此值可以改变线条的选中难易程度*/) return true;//误差值，也可以通过函数参数传进来

            return false;
        }
        //************************************************************************************
        public virtual bool equalTo(OriginalLine line)
        {
            if (this.startPoint == line.startPoint && this.endPoint == line.endPoint)
                return true;
            else
                return false;
        }
        //************************************************************************************
        public Point StartPoint
        {
            get
            {
                return startPoint;
            }
            set
            {
                startPoint = value;
            }
        }
        public Point EndPoint
        {
            get
            {
                return endPoint;
            }
            set
            {
                endPoint = value;
            }
        }
        public bool IsSelected
        {
            get
            {
                return isSelected;
            }
            set
            {
                isSelected = value;
            }
        }
        public Size StartDiagramSize
        {
            get
            {
                return startDiagramSize;
            }
            set
            {
                startDiagramSize = value;
            }
        }
        public Size EndDiagramSize
        {
            get
            {
                return endDiagramSize;
            }
            set
            {
                endDiagramSize = value;
            }
        }
        //************************************************************************************
        
    }
}
